/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uk.ac.bath.domains.mover;

import java.util.Collection;
import java.util.Vector;
import uk.ac.bath.base.Cell;
import uk.ac.bath.base.CellFactoryIF;
import uk.ac.bath.base.EnvironmentIF;
import uk.ac.bath.base.RecursiveMachine;
import uk.ac.bath.base.PalleteIF;
import uk.ac.bath.base.Point;

import uk.ac.bath.machine.neural.NeuralMachine;
import uk.ac.bath.machine.neural.NeuralPallete;
import uk.ac.bath.util.MyRandom;
import uk.ac.bath.util.Tweakable;
import uk.ac.bath.util.TweakableInt;

/**
 *
 * @author pjl
 */
public class MoverCellMrk1NeuralFactory implements MoverCellFactoryIF {

    public Vector<Tweakable> tweaks = new Vector<Tweakable>();
    public TweakableInt maxOperatorsPerCell =
            new TweakableInt(tweaks, 10, 1000, 50, "MaxMachineSize");
    public TweakableInt initFit =
            new TweakableInt(tweaks, 0, 200, 5, "InitialFitness");


    final public static int minOperatorsPerCell = 10;

    PalleteIF pallete=new NeuralPallete();
    private MoverEnvironment env;

    public MoverCellMrk1NeuralFactory() {
        tweaks.addAll(MoverCellMrkI.tweaks);
        tweaks.addAll(NeuralMachine.tweaks);
    }

    public void setEnvironment(MoverEnvironment env) {
        this.env=(MoverEnvironment) env;
    }


    public Cell createRandomCell(Point p) {

        int nOps = MoverCellMrkI.minOperatorsPerCell +
                MyRandom.nextInt(maxOperatorsPerCell.intValue() - minOperatorsPerCell);
        RecursiveMachine m = new NeuralMachine(nOps,pallete);

        int cid = Cell.nextId();
        String tag = "MrkI:" + cid;

        return new MoverCellMrkI(env,m, p,
                initFit.doubleValue(),
                cid, 0, 0, tag);
    }


    public void mutate(Cell cell) {
        MoverCell mv = (MoverCell) cell;
        ((NeuralMachine) mv.getMachine()).mutate();
    }

    public Collection<Tweakable> getTweaks() {
        return tweaks;
    }

    public double getInitFitness() {
      return initFit.doubleValue();
    }


}
